/* =========================================================
   ЕГЭ НАЛЕГКЕ — ШАПКА УРОКА
   ========================================================= */

(function () {

  "use strict";


  /* =======================================================
     ВСПОМОГАТЕЛЬНОЕ
     ======================================================= */

  function clean(value) {

    return String(value || "")
      .replace(/\u00A0/g, " ")
      .replace(/\s+/g, " ")
      .trim();

  }


  /* =======================================================
     ВИДИМОЕ ОПИСАНИЕ

     Всё после первого | — техническая информация.
     
     Например:

     В этом уроке разберём тему | база | неделя 1 | сортировка

     Пользователь увидит только:

     В этом уроке разберём тему
     ======================================================= */

  function getVisibleDescription(description) {

    if (!description) {
      return "";
    }

    var text = clean(description);

    return clean(
      text.split("|")[0]
    );

  }


  /* =======================================================
     ТИП УРОКА
     ======================================================= */

function getTypeLabel(header) {

  var title =
    header.querySelector(".header-view h2");

  var description =
    header.querySelector(".lesson-description-value");

  var source = [
    document.title,

    title
      ? clean(title.textContent)
      : "",

    description
      ? getVisibleDescription(description.textContent)
      : ""
]


  if (
    /вебинар|созвон|трансляц|практик/
      .test(source)
  ) {
    return "вебинар";
  }


  if (
  /домашнее задание/
  .test(source)
) {
  return "домашнее задание";
}


  if (
    /данетк/
      .test(source)
  ) {
    return "данетка";
  }
    
    if (
    /пробн/
      .test(source)
  ) {
    return "пробник";
  }


  if (
    /тест|тестирован/
      .test(source)
  ) {
    return "тест";
  }


  if (
    /видеоурок|видео-урок|видео урок/
      .test(source)
  ) {
    return "видеоурок";
  }


  return "урок";

}


  /* =======================================================
     ЧИСТОЕ НАЗВАНИЕ УРОКА
     ======================================================= */

  function prepareTitle(header) {

    var title =
      header.querySelector(
        ".header-view h2"
      ) ||
      header.querySelector("h2");


    if (!title) {
      return;
    }


    /*
     * Сохраняем оригинальное название,
     * чтобы оно не потерялось при повторном запуске.
     */

    if (
      !title.dataset.enlOriginalTitle
    ) {

      title.dataset.enlOriginalTitle =
        clean(title.textContent);

    }


    /*
     * Само название урока больше
     * не показываем.
     */

    title.textContent = "";

    title.classList.add(
      "enl-lesson-title"
    );

    title.classList.add(
      "enl-lesson-title-hidden"
    );

  }

     /* =======================================================
     ОПИСАНИЕ

     Показываем только то,
     что находится ДО первого |

     Например:

     Реальное описание | due=24.08 | база | №24

     Пользователь увидит:

     Реальное описание
     ======================================================= */

  function prepareDescription(header) {

    var description =
      header.querySelector(
        ".lesson-description-value"
      );


    if (!description) {
      return;
    }


    if (
      !description.dataset.enlOriginalDescription
    ) {

      description.dataset.enlOriginalDescription =
        description.textContent;

    }


    var visible =
      getVisibleDescription(
        description.dataset.enlOriginalDescription
      );


    description.textContent =
      visible;

  }

  /* =======================================================
     ЗАПОМИНАЕМ ТРЕНИНГ, ИЗ КОТОРОГО ОТКРЫТ УРОК
     ======================================================= */

  function rememberLessonTraining() {

    var referrer = document.referrer || "";

    /*
     * Если урок открыт непосредственно из тренинга,
     * сохраняем именно этот тренинг.
     *
     * Это может быть:
     * База
     * Хард
     * любой другой подтренинг.
     */

    if (
      /\/teach\/control\/stream\/view/i.test(referrer)
    ) {

      try {

        sessionStorage.setItem(
          "enlLessonTraining",
          referrer
        );

      } catch (e) {}

    }

  }


  /* =======================================================
     ПОЛУЧАЕМ СОХРАНЁННЫЙ ТРЕНИНГ
     ======================================================= */

  function getLessonTraining() {

    try {

      return sessionStorage.getItem(
        "enlLessonTraining"
      ) || "";

    } catch (e) {

      return "";

    }

  }
  /* =======================================================
     РОДИТЕЛЬСКИЕ ССЫЛКИ
     ======================================================= */

  function getParentLinks() {

    return Array.prototype.slice.call(
      document.querySelectorAll(
        ".breadcrumb a[href], " +
        ".breadcrumbs a[href], " +
        'a[href*="/teach/control/stream/view"]'
      )
    )
      .filter(function (link) {

        return !link.closest(
          ".gc-account-leftbar, " +
          ".lesson-header-block"
        );

      });

  }


  /* =======================================================
     НЕДЕЛЯ
     ======================================================= */

function findWeekLink(links) {

  /*
   * Ищем тренинг, в котором непосредственно находится
   * текущий урок.
   *
   * Приоритет:
   * 1. хлебные крошки;
   * 2. ссылка на текущий stream;
   * 3. старый fallback.
   */

  var breadcrumbLinks =
    Array.prototype.slice.call(
      document.querySelectorAll(
        ".breadcrumb a[href*='/teach/control/stream/view'], " +
        ".breadcrumbs a[href*='/teach/control/stream/view']"
      )
    )
    .filter(function (link) {

      return !link.closest(
        ".gc-account-leftbar, " +
        ".lesson-header-block"
      );

    });


  /*
   * В хлебных крошках обычно:
   *
   * курс
   * → уровень
   * → база / хард
   * → неделя
   * → урок
   *
   * Поэтому ищем наиболее подходящий именно
   * учебный тренинг, а не верхний раздел.
   */

  var trainingLink =
    breadcrumbLinks
      .slice()
      .reverse()
      .find(function (link) {

        var text =
          clean(link.textContent)
            .toLowerCase();


        /*
         * Если ссылка явно обозначает неделю —
         * это лучший вариант.
         */

        if (
          /недел[яи]\s*№?\s*\d+/i
            .test(text)
        ) {
          return true;
        }


        /*
         * Также подходят даты периода:
         * 22.08–28.08 и т.п.
         */

        if (
          /(?:с\s*)?\d{1,2}[./-]\d{1,2}.*(?:по|—|–|-).*\d{1,2}[./-]\d{1,2}/i
            .test(text)
        ) {
          return true;
        }


        return false;

      });


  if (trainingLink) {
    return trainingLink;
  }


  /*
   * Если название недели не содержит слова «неделя»,
   * ищем среди последних ссылок на stream.
   *
   * Но исключаем очевидные верхние разделы.
   */

  var candidates =
    breadcrumbLinks.filter(function (link) {

      var text =
        clean(link.textContent)
          .toLowerCase();


      if (
        /разделение уровней|уровн|главн|курс/
          .test(text)
      ) {
        return false;
      }


      return true;

    });


  if (candidates.length) {

    return candidates[
      candidates.length - 1
    ];

  }


  return null;

}


  /* =======================================================
     СТАРАЯ ЛОГИКА БАЗА / ХАРД
     НУЖНА ТОЛЬКО КАК FALLBACK
     ======================================================= */

  function findChecklistLink(
    links,
    weekLink
  ) {

    var explicit =
      links
        .slice()
        .reverse()
        .find(function (link) {

          var text =
            clean(
              link.textContent
            )
            .toLowerCase();


          return (
            /базов.*уров/
              .test(text) ||

            /хард.*уров/
              .test(text) ||

            text === "база" ||

            text === "хард"
          );

        });


    if (explicit) {
      return explicit;
    }


    var candidates =
      links.filter(function (link) {

        return (
          link !== weekLink &&

          /\/teach\/control\/stream\/view/
            .test(
              link.href || ""
            )
        );

      });


    return candidates.length
      ? candidates[
          candidates.length - 1
        ]
      : weekLink;

  }


/* =======================================================
   ГЛАВНАЯ СТРАНИЦА КУРСА ИЗ ХЛЕБНЫХ КРОШЕК GETCOURSE

   Структура:
   1. Список тренингов
   2. Годовой курс ← ЭТУ ССЫЛКУ БЕРЁМ
   3. Раздел
   4. Неделя
   5. Текущий урок

   То есть берём вторую ссылку хлебных крошек.
   ======================================================= */

function findParentCourseLink() {

  var breadcrumbs =
    document.querySelector(
      ".breadcrumb, .breadcrumbs"
    );


  if (!breadcrumbs) {
    return null;
  }


  var links =
    Array.prototype.slice.call(
      breadcrumbs.querySelectorAll(
        "a[href]"
      )
    );


  links =
    links.filter(function (link) {

      return !link.closest(
        ".gc-account-leftbar, " +
        ".lesson-header-block"
      );

    });


  /*
   * Нам нужна вторая хлебная крошка:
   *
   * [0] Список тренингов
   * [1] Годовой курс
   * [2] Архив
   * [3] Сентябрь
   * [4] Неделя
   */

  if (links.length >= 2) {

    return links[1];

  }


  /*
   * Если по какой-то причине второй ссылки нет,
   * ничего не придумываем.
   */

  return null;

}

  /* =======================================================
     СОЗДАНИЕ ССЫЛКИ
     ======================================================= */

  function makeLink(
    href,
    text,
    className
  ) {

    var link =
      document.createElement("a");


    link.href =
      href || "#";


    link.textContent =
      text;


    link.className =
      className;


    return link;

  }


  /* =======================================================
     ПРИМЕНЯЕМ ШАПКУ
     ======================================================= */

  function apply() {

    var header =
      document.querySelector(
        ".lesson-header-block"
      );


    if (!header) {
      return false;
    }


    header.classList.add(
      "enl-lesson-header"
    );


    header.setAttribute(
      "data-enl-label",
      getTypeLabel(header)
    );


    prepareTitle(header);

    prepareDescription(header);


    var navigation =
      header.querySelector(
        ".lesson-navigation"
      );


    var row =
      navigation &&
      navigation.querySelector("tr");


    if (!row) {
      return true;
    }


    /*
     * Если уже обработали эту шапку —
     * повторно ничего не делаем.
     */

    if (
      row.dataset.enlReady === "1"
    ) {
      return true;
    }


    var cells =
      Array.prototype.slice.call(
        row.children
      )
      .filter(function (element) {

        return (
          element.tagName === "TD"
        );

      });


    if (cells.length < 3) {
      return true;
    }


    /* =====================================================
       СНАЧАЛА СОХРАНЯЕМ РОДНУЮ НАВИГАЦИЮ
       ===================================================== */

    var nativePrev =
      cells[0]
        .querySelector(
          "a[href]"
        );


    var nativeNext =
      cells[2]
        .querySelector(
          "a[href]"
        );


    var prevHref =
      nativePrev
        ? nativePrev.href
        : "";
      
    var nextHref =
      nativeNext
        ? nativeNext.href
        : "";


    /* =====================================================
       ИЩЕМ ССЫЛКУ НА ГЛАВНЫЙ ТРЕНИНГ
       ===================================================== */

    var parentCourseLink =
      findParentCourseLink();


    var parentHref =
      parentCourseLink &&
      parentCourseLink.href
        ? parentCourseLink.href
        : "";


    /* =====================================================
       FALLBACK

       Если скрытого HTML нет —
       используем старую логику.
       ===================================================== */

    var parentLinks =
      getParentLinks();


    var weekLink =
      findWeekLink(
        parentLinks
      );


    var checklistLink =
      findChecklistLink(
        parentLinks,
        weekLink
      );


       /* =====================================================
       ТРЕНИНГ, ИЗ КОТОРОГО ОТКРЫТ УРОК
       ===================================================== */

    var lessonTrainingHref =
      getLessonTraining();


    var fallbackHref =
      lessonTrainingHref ||
      (
        weekLink &&
        weekLink.href
          ? weekLink.href
          : "#"
      );


    /*
     * Если предыдущей задачи нет,
     * возвращаемся именно в тот тренинг,
     * из которого ученик открыл урок.
     */

    var previousFallbackHref =
      lessonTrainingHref ||
      fallbackHref;
      


    /*
     * Главная:
     *
     * 1. скрытый HTML
     * 2. старая ссылка
     * 3. #
     */

    var homeHref =
      parentHref ||
      fallbackHref;


    /* =====================================================
       1. ПРЕДЫДУЩАЯ ЗАДАЧА
       ===================================================== */

    cells[0].innerHTML = "";


    if (prevHref) {

  cells[0].appendChild(
    makeLink(
      prevHref,
      "назад",
      "enl-lesson-nav-button " +
      "enl-lesson-nav-back"
    )
  );


} else {

  cells[0].appendChild(
    makeLink(
      previousFallbackHref,
      "назад",
      "enl-lesson-nav-button " +
      "enl-lesson-nav-back"
    )
  );

}


    /* =====================================================
       2. ГЛАВНАЯ
       ===================================================== */

    cells[1].innerHTML = "";


    var middle =
      makeLink(
        homeHref,
        "вернуться на главную",
        "enl-lesson-nav-button " +
        "enl-lesson-nav-week"
      );


    if (
      homeHref === "#"
    ) {

      middle.addEventListener(
        "click",
        function (event) {

          event.preventDefault();

          window.history.back();

        }
      );

    }


    cells[1].appendChild(
      middle
    );


    /* =====================================================
       3. СЛЕДУЮЩАЯ ЗАДАЧА
       ===================================================== */

    cells[2].innerHTML = "";


    if (nextHref) {

      cells[2].appendChild(
        makeLink(
          nextHref,
          "дальше",
          "enl-lesson-nav-button " +
          "enl-lesson-nav-next"
        )
      );


    } else {

  cells[2].appendChild(
    makeLink(
      lessonTrainingHref ||
      fallbackHref,
      "дальше",
      "enl-lesson-nav-button " +
      "enl-lesson-nav-next"
    )
  );

}


    /* =====================================================
       КЛАССЫ ЯЧЕЕК
       ===================================================== */

    cells.forEach(
      function (cell) {

        cell.classList.add(
          "enl-lesson-nav-cell"
        );

      }
    );


    row.dataset.enlReady =
      "1";


    return true;

  }


  /* =======================================================
     ЗАПУСК
     ======================================================= */

   function start() {

    rememberLessonTraining();

    apply();

    setTimeout(
      apply,
      300
    );

    setTimeout(
      apply,
      800
    );

    setTimeout(
      apply,
      1600
    );

    setTimeout(
      apply,
      3000
    );

  }


  if (
    document.readyState ===
    "loading"
  ) {

    document.addEventListener(
      "DOMContentLoaded",
      start,
      {
        once: true
      }
    );


  } else {

    start();

  }

})();

$(function(){

$('.al_main-banner.archive-banner').each(function(){

    const banner = $(this);

    const img = banner.find('.al_mb-img img');


    if(img.length){

        img.attr(
            'src',
            'https://fs.getcourse.ru/fileservice/file/download/a/176040/sc/121/h/a050b098f4f260e51ab26022cd7fb413.webp'
        );

    }

});

});

$(function(){

    $('.debt-banner').each(function(){

        const banner = $(this);
        const img = banner.find('.al_mb-img img');

        img.attr(
            'src',
            'https://fs.getcourse.ru/fileservice/file/download/a/176040/sc/215/h/3a1550d50acad2ac7951307efda19b04.webp'
        );

    });

});
$(function() {

    $('.archive-banner .al_mbBtn')
        .text('← вернуться назад');

});


/* ============================================================
   ЕГЭ Налегке — ПЛАШКА «ВАЖНО»: вариант про CloudText
   Версия 4.0 (06.09.2026)

   КУДА: в тему, к остальным скриптам (файл JS оформления уроков).

   ЧТО ДЕЛАЕТ. Находит блоки с классом enl-note--ct, читает данные
   ученика из служебного div внутри, показывает одно состояние из
   шести — и, если ученик ещё не зарегистрирован, даёт РАБОЧУЮ
   кнопку: регистрация запускается прямо со страницы урока.

   &#9888;&#65039; ОБЫЧНЫЕ ПЛАШКИ НЕ ТРОГАЕТ. Блок с одним классом enl-note для
   скрипта не существует: он ищет только enl-note--ct.

   ============================================================
   ПОЧЕМУ КНОПКА УСТРОЕНА ИМЕННО ТАК
   ============================================================

   Регистрацию запускает не наш сервис, а форма GetCourse: её
   отправка включает процесс, процесс зовёт сервис, сервис пишет
   поля обратно. Сама форма — блок на странице /cloudtext-panel2.

   &#9888;&#65039; ЗАМЕРЕНО 06.09.2026: GetCourse принимает отправку этой формы
   СО СТРАНИЦЫ УРОКА, где самой формы нет. Ответ
   {"success":true,"formProcessed":true}, и через семь секунд в
   логе сервиса появилась запись по этому ученику. Поэтому копию
   формы в каждый урок класть не нужно — достаточно знать её адрес.

   &#9888;&#65039; Первая версия вместо кнопки уводила ученика ссылкой на
   /cloudtext-panel2. Так делать нельзя: это техническая страница,
   она не оформлена для детей, и с урока ребёнок уходил насовсем.

   &#9888;&#65039; ОТВЕТА ОТ СЕРВИСА КНОПКА НЕ ПОЛУЧАЕТ И ПОЛУЧИТЬ НЕ МОЖЕТ:
   запрос уходит в GetCourse, а не к нам. Результат приезжает
   другой дорогой — сервис сам записывает поля через API, а
   подставляются они на сервере, при загрузке страницы. Отсюда
   единственный способ увидеть результат: подождать и перезагрузить.

   &#9888;&#65039; СЧЁТЧИК ПОПЫТОК ЖИВЁТ В АДРЕСЕ СТРАНИЦЫ (#ct=N). Он должен
   пережить перезагрузку, а их несколько подряд; в адресе он
   переживает её всегда и не зависит ни от хранилища браузера, ни
   от того, что мы внутри iframe.
   ============================================================ */

(function () {
    'use strict';

    /* &#9888;&#65039; ЕДИНСТВЕННОЕ ЧИСЛО, КОТОРОЕ ПРИДЁТСЯ МЕНЯТЬ РУКАМИ.
       Это id блока ФОРМЫ на странице /cloudtext-panel2 — не id
       процесса и не «код блока» вида b-45b92, который виден в
       редакторе. Взять его можно так: открыть панель, в коде
       страницы найти form[action*="block-public/process"] и
       посмотреть число в его адресе.

       Если форму на панели пересоберут, число изменится, и кнопка
       в уроках перестанет отправлять. Проверяется за минуту. */
    var ID_ФОРМЫ = 2248684871;

    /* Через сколько секунд после отправки перезагрузить страницу.
       Процесс стартует примерно за секунду, дальше работает сервис:
       CloudText, таблица кураторов, запись полей обратно. Шесть
       секунд — с запасом. */
    var ПАУЗА = 6;

    /* Сколько раз перезагружаться, пока не появится результат.
       Шесть попыток по шесть секунд — примерно полминуты. Дальше
       показываем отказ: молча перезагружать вечно нельзя. */
    var ПОПЫТОК = 6;


    function настроить(блок) {
        if (блок.getAttribute('data-gotov') === '1') return;
        блок.setAttribute('data-gotov', '1');

        var данные = блок.querySelector('.enl-note__data');
        if (!данные) return;          /* блок собран без служебной строки */

        function сырое(имя) {
            return (данные.getAttribute('data-' + имя) || '').trim();
        }

        function поле(имя) {
            var з = сырое(имя);
            /* &#9888;&#65039; ОТКАЗ В БЕЗОПАСНУЮ СТОРОНУ. Если GetCourse не знает
               подстановки, в атрибуте останется её текст в фигурных
               скобках — «{last_name}». Считать это значением нельзя:
               мы бы либо решили, что поле заполнено, либо заперли бы
               ученику регистрацию из-за опечатки в имени поля. */
            if (з.indexOf('{') !== -1 && з.indexOf('}') !== -1) return '';
            return з;
        }

        function показать(имя) {
            var все = блок.querySelectorAll('[data-state]');
            for (var i = 0; i < все.length; i++) {
                все[i].style.display =
                    (все[i].getAttribute('data-state') === имя) ? 'block' : 'none';
            }
        }

        /* --- счётчик попыток в адресе страницы --- */
        function попытка() {
            var m = /[#&]ct=(\d+)/.exec(window.location.hash);
            return m ? parseInt(m[1], 10) : 0;
        }

        function перезагрузить(номер) {
            var чистый = window.location.hash
                .replace(/[#&]ct=\d+/, '').replace(/^#/, '');
            window.location.hash = (чистый ? чистый + '&' : '') + 'ct=' + номер;
            window.location.reload();
        }

        function ждать() {
            var н = попытка();
            var медленно = блок.querySelector('.enl-note__slow');
            if (н >= ПОПЫТОК) {
                if (медленно) медленно.style.display = 'block';
                return;
            }
            setTimeout(function () { перезагрузить(н + 1); }, ПАУЗА * 1000);
        }

        /* --- отправка ---
           Шлём ровно те поля, что шлёт настоящая форма на панели.
           Сняты с неё 06.09.2026. Запрос уходит на свой же домен,
           поэтому cookie сессии уходят сами и GetCourse видит, кто
           нажал; кого регистрировать, определяет formParams[email]. */
        function отправить() {
            var почта = поле('email');
            if (!почта) return;

            var кнопки = блок.querySelectorAll('.enl-note__btn');
            for (var i = 0; i < кнопки.length; i++) {
                кнопки[i].disabled = true;
                кнопки[i].style.opacity = '0.6';
            }

            var тело = new URLSearchParams();
            тело.set('formParams[setted_offer_id]', '');
            тело.set('formParams[willCreatePaidDeal]', '0');
            тело.set('__gc__internal__form__helper',
                     window.location.origin + '/cloudtext-panel2');
            тело.set('__gc__internal__form__helper_ref', window.location.href);
            тело.set('formParams[email]', почта);

            fetch(window.location.origin +
                  '/pl/lite/block-public/process?id=' + ID_ФОРМЫ, {
                method: 'POST',
                credentials: 'same-origin',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                    'X-Requested-With': 'XMLHttpRequest'
                },
                body: тело.toString()
            }).then(function () {
                показать('waiting');
                setTimeout(function () { перезагрузить(1); }, ПАУЗА * 1000);
            }).catch(function () {
                /* &#9888;&#65039; Не молчим: ученик должен понимать, что нажатие не
                   прошло, а не смотреть на замершую кнопку. */
                показать('failed');
            });
        }

        /* --- разбор состояния --- */
        var статус = поле('status');
        var почта  = поле('email');
        var пароль = поле('password');
        var ид     = поле('ctid');

        var естьПара =
            (поле('mentor-obsh') && поле('checker-obsh')) ||
            (поле('mentor-hist') && поле('checker-hist'));

        /* Подставить логин и пароль везде, где они упомянуты. */
        var места = блок.querySelectorAll('[data-put]');
        for (var m = 0; m < места.length; m++) {
            места[m].textContent =
                (места[m].getAttribute('data-put') === 'email') ? почта : пароль;
        }

        /* Кнопки — сразу, до всех return: иначе на части веток
           обработчик не навешивался бы. */
        var кнопки = блок.querySelectorAll('.enl-note__btn[data-do="register"]');
        for (var k = 0; k < кнопки.length; k++) {
            кнопки[k].addEventListener('click', отправить);
        }

        var зарегистрирован =
            статус === 'зарегистрирован' || статус === 'частично зарегистрирован';

        /* 1. фамилия — ученик исправит сам.
           Проверяем, только если подстановка сработала: пустая строка
           значит «фамилии нет», строка со скобками — «GetCourse такого
           поля не знает», и тогда мы молчим. */
        var фамилияСырая = сырое('lastname');
        var подстановкаРаботает =
            !(фамилияСырая.indexOf('{') !== -1 && фамилияСырая.indexOf('}') !== -1);

        if (!зарегистрирован && подстановкаРаботает && !поле('lastname')) {
            показать('nolastname');
            return;
        }

        /* 2. кураторов ещё нет. Только для тех, кто ЕЩЁ не
           зарегистрирован: у того, кто уже в группах, отсутствие
           второй пары — не его забота, второй предмет допишется сам. */
        if (!зарегистрирован && !естьПара) {
            показать('nocurator');
            return;
        }

        /* 3. аккаунт есть */
        if (зарегистрирован || ид) {
            показать(пароль ? 'ready' : 'readynopass');
            return;
        }

        /* 4. сервис уже работает */
        if (статус === 'запрос отправлен') {
            показать('waiting');
            ждать();
            return;
        }

        /* 5. &#9888;&#65039; МЫ УЖЕ НАЖИМАЛИ, А СТАТУСА ВСЁ ЕЩЁ НЕТ.
           Счётчик ct= ставим только мы и только после отправки. Если
           он больше нуля, значит запрос ушёл. Без этой ветки пустой
           статус после нажатия снова показывал бы кнопку: страница
           мигнула, кнопка на месте, ни ошибки, ни успеха. */
        if (попытка() > 0 && !статус) {
            if (попытка() < ПОПЫТОК) {
                показать('waiting');
                ждать();
                return;
            }
            показать('failed');
            return;
        }

        /* 6. не зарегистрирован: пусто или ошибка.
           При ошибке показываем ту же кнопку — повторное нажатие
           часто решает дело (лимит CloudText, срыв сессии), — но
           добавляем строку с причиной, чтобы ученик не гадал. */
        показать('register');
        if (статус.indexOf('ошибка') === 0) {
            var причина = блок.querySelector('.enl-note__why');
            if (причина) {
                причина.textContent = 'прошлая попытка не удалась: ' +
                    статус.replace(/^ошибка:\s*/, '');
                причина.style.display = 'block';
            }
        }
    }

    function пройти() {
        var блоки = document.querySelectorAll('.enl-note--ct');
        for (var i = 0; i < блоки.length; i++) настроить(блоки[i]);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', пройти);
    } else {
        пройти();
    }

    /* &#9888;&#65039; Страховка для блоков, появившихся позже: урок в GetCourse
       иногда достраивается после DOMContentLoaded. Проверка
       document.body обязательна — тема подключается в <head>, и без
       неё observe() падает с «parameter 1 is not of type Node».
       Ровно на этом спотыкается «разворот аккордеонов». */
    var таймер = null;
    var наблюдатель = new MutationObserver(function () {
        clearTimeout(таймер);
        таймер = setTimeout(пройти, 120);
    });

    function запустить() {
        наблюдатель.observe(document.body, { childList: true, subtree: true });
    }

    if (document.body) {
        запустить();
    } else {
        document.addEventListener('DOMContentLoaded', запустить);
    }
})();